//
//  METagView.swift
//  TagList
//
//  Created by tong on 15/11/10.
//  Copyright © 2015年 tong. All rights reserved.
//

import Foundation
import UIKit

import Eelay
extension METagListView
{    
    public func addOneTag(tag:NSMutableDictionary)
    {
        let count = self.subviews.count
        let one =  self.tagType.init()
        one.tag = count
        one.mo.model = tag
        weak var wself = self
        
        one.deletate = self
        
        one.pressedAction = {
            (index:Int,selected:Bool,obj:AnyObject,tview:METagView)
            in
            
            
       
            guard let ws = wself else {
                return
            }
            
            
//            print("====----kkk|\(self.selectMode)==|\(self.selectMode.max)===|\(self.selectMode.min)")
            if selected{
                let vs = ws.values
                let limit_num = ws.selectMode.max
                
                if vs.count >= limit_num{
                    wself?.limit_select_prompt(limit_num)
                    return
                }
            }
            
            switch ws.selectMode {
            case .singleNoToggle:
                if let dict = obj as? NSMutableDictionary
                {
                    if dict["selected","NO"] == "YES"
                    {
                        return
                    }
                }
                wself?.allTagToNormalStatus()
            case .singleToggle:
                wself?.allTagToNormalStatus()
            default:
                break
            }
            
            
            if let dict = obj as? NSMutableDictionary
            {
                if selected{
                    dict.setObject("YES", forKey: "selected" as NSCopying)
                }
                else
                {
                    dict.setObject("NO", forKey: "selected" as NSCopying)
                }
            }
            wself?.updateAllTagStatus()
            wself?.finishOneSelect()
            wself?.selectedAction(index, selected,obj,tview)
            
        }
        self.addSubview(one)
        self.tags.append(tag)
    }
    
    public func add(tag:NSMutableDictionary)
    {
        self.addOneTag(tag: tag)
        self.didSetup = false
        self.invalidateIntrinsicContentSize()
    }
    
    
    public func add(tags:NSMutableArray)
    {
        
        for one in tags
        {
            if let dict = one as? NSMutableDictionary
            {
                self.addOneTag(tag: dict)
            }
        }
        self.didSetup = false
        
        self.invalidateIntrinsicContentSize()
//        self.setNeedsLayout()
//        self.setNeedsDisplay()
//        
//        self.superview?.setNeedsLayout()
//        self.superview?.setNeedsDisplay()
    }
    
    public func remove()
    {
        self.tags.removeAll()
        
        for view in self.subviews
        {
            view.removeFromSuperview()
        }
        
        
        self.invalidateIntrinsicContentSize()
    }
    
    
    public func remove(tag:NSMutableDictionary)
    {
        if let index = self.tags.firstIndex(of: tag)
        {
            self.tags.remove(at: index)
            self.subviews[index].removeFromSuperview()
            self.didSetup = false
            
            self.invalidateIntrinsicContentSize()
        }
    }
    
    public func remove(index:Int)
    {
        if index < self.tags.count
        {
            let obj = self.tags[index] as NSMutableDictionary
            self.remove(tag:obj)
        }
    }
    
    
    
    func updateAllTagStatus()
    {
        for view in self.subviews
        {
            if let tag_v = view as? METagView
            {
                tag_v.mo_model_reload()
            }
        }
    }
    
    
    func allTagToNormalStatus()
    {
        for one in self.tags
        {
            one.setObject("NO", forKey: "selected" as NSCopying)
        }
    }
    
    
}


public enum TagSelectMode{
    
    
    public var value:String{
        get{
            switch self {
            case .singleToggle:
                return "singleToggle"
            case .singleNoToggle:
                return "singleNoToggle"
            case .mutil(min: let min, max: let max, minMark: let minS, maxMark: let maxS):
                let minV = min ?? -100
                let maxV = max ?? 1000000
                let dict:[String:Any] = [
                    "min":minV,
                    "max":maxV,
                    "minMark":minS,
                    "maxMark":maxS
                ]
                return dict.rawJson ?? "{}"
            }
        }
    }
    
    public static func new(value:String) ->TagSelectMode{
        switch value {
        case "singleToggle":
            return .singleToggle
        case "singleNoToggle":
            return .singleNoToggle
        default:
            guard let dict = value.JsonDictionary else{return .singleToggle}
            let max = dict[int:"max",100000]
            let min = dict[int:"min",-1]
            let maxS = dict["maxMark",""]
            let minS = dict["minMark",""]
            return .mutil(min: min, max: max, minMark: minS, maxMark: maxS)
        }
    }
    
    
    public var min:Int{
        switch self {
        case .mutil(min: let min, max: _, minMark: _, maxMark: _):
            return min ?? 0
        default:
            return 0
        }
    }
    
    public var max:Int{
        switch self {
        case .mutil(min: _, max: let max, minMark: _, maxMark: _):
            return max ?? 10000000
        default:
            return 100
        }
    }
    
    public var maxMark:String{
        switch self {
        case .mutil(min: _, max: _, minMark: _, maxMark: let mark):
            return mark
        default:
            return ""
        }
    }
    public var minMark:String{
        switch self {
        case .mutil(min: _, max: _, minMark: let mark, maxMark: _):
            return mark
        default:
            return ""
        }
    }

   
    case mutil (min:Int?,max:Int?,minMark:String,maxMark:String)
    case singleToggle
    case singleNoToggle
}

public class METagListView: UIView,MoAtrributeProtocol,EeActionDelegate {
    public func mo_set_controller(controller: UIViewController) {
        
    }
    
    public func active(onwer: Any, actionID: String, data: NSMutableDictionary) {
        self.delegate?.active(onwer: onwer, actionID: actionID, data: data)
    }
    
    public weak var delegate:EeActionDelegate?

    
    public var tagType:METagView.Type = TagV.self
    
    public var tags = [NSMutableDictionary]()
    
    public var tags_constraints = [NSLayoutConstraint]()
    
    public var padding = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
    
    public var lineSpace:CGFloat = 8
    
    public var singleLine = false
    
    public var insets:CGFloat = 8
    
    var didSetup:Bool = false
    
    public var selectMode:TagSelectMode = .singleToggle
    public var selectModeValue:String = "singleToggle"{
        didSet{
            self.selectMode = TagSelectMode.new(value: selectModeValue)
        }
    }

    
    
    public var limit_select_count = 100000
    public var limit_select_prompt:(Int) ->Void = {_ in}
    
    
    
    public var select_ids = [String]()
    
    
    public var option_node = "id"
    public var values : [String]
    {
        get{
            var vs = [String]()
            vs.removeAll()
            for obj in self.tags
            {
                if obj["selected","NO"] == "YES"
                {
                    vs.append(obj["\(option_node)",""])
                }
            }
            return vs
        }
    }
    
    
    func finishOneSelect() {
        
    }
    
    public var selectedAction:(_ index:Int,_ selected:Bool,_ obj:AnyObject,_ tagV:METagView)->Void =
    {
        _,_,_,_ in
    }
    
    public var preferredMaxLayoutWidth:CGFloat = UIScreen.main.bounds.size.width
    {
        willSet(newValue){
            if newValue != preferredMaxLayoutWidth
            {
                self.didSetup = false
            }
        }
        didSet{
            self.didSetup = false
            
            self.setNeedsUpdateConstraints()
        }
    }
    
    override public func updateConstraints() {
        
        updateWrappingConstrains()
        super.updateConstraints()
    }
    
    
    override public var intrinsicContentSize: CGSize
    {
        
        if self.tags.count < 0
        {
            return CGSize.zero
        }
        
        let subviews = self.subviews
        var previewsView:UIView?
        let leftOffset = self.padding.left;
        let bottomOffset = self.padding.bottom
        let rightOffset = self.padding.right
        let itemMargin = self.insets
        let topPadding = self.padding.top
        let itemVerticalMargin = self.lineSpace
        var currentX = leftOffset
        var intrinsicHeight = topPadding
        var intrinsicWidth = leftOffset
        
        
        if !self.singleLine && (self.preferredMaxLayoutWidth > 0)
        {
            var lineCount = 0
            for (_,view) in subviews.enumerated()
            {
                let size = view.intrinsicContentSize
                if let _ = previewsView
                {
                    let width = size.width
                    currentX += itemMargin
                    
                    let  info_w:CGFloat = currentX + width + rightOffset;
                    
                    if info_w <= self.preferredMaxLayoutWidth
                    {
                        currentX += size.width
                    }
                    else
                    {
                        //New line
                        lineCount += 1
                        currentX = leftOffset + size.width
                        intrinsicHeight += size.height
                    }
                }
                else
                {
                    //First one
                    lineCount += 1
                    intrinsicHeight += size.height
                    currentX += size.width
                }
                previewsView = view
                
                intrinsicWidth = max(intrinsicWidth, currentX + rightOffset);
            }
            intrinsicHeight += bottomOffset + itemVerticalMargin * CGFloat((lineCount - 1))
        }
        else
        {
            for view in subviews
            {
                let size = view.intrinsicContentSize
                intrinsicWidth += size.width
            }
            intrinsicWidth += itemMargin * CGFloat((subviews.count - 1)) + rightOffset
            
            if let f_view = subviews.first
            {
                intrinsicHeight  += f_view.intrinsicContentSize.height + bottomOffset
            }
            
        }
        
        let _size = CGSize(width: intrinsicWidth, height: intrinsicHeight)
        
        return _size
    }
    
    
    override public func layoutSubviews() {
        if !self.singleLine
        {
            //            self.preferredMaxLayoutWidth = self.frame.size.width
        }
        
        super.layoutSubviews()
    }
    
    
    
    func updateWrappingConstrains()
    {
        
        
        if self.didSetup{
            return
        }
        if self.tags.count <= 0
        {
            return
        }
        
        
        self.removeConstraints(tags_constraints)
        tags_constraints.removeAll()
        
        
        let subviews = self.subviews;
        var previewsView:UIView?
        let leftOffset = self.padding.left;
        let bottomOffset = self.padding.bottom;
        let rightOffset = self.padding.right;
        let itemMargin = self.insets;
        let topPadding = self.padding.top;
        let itemVerticalMargin = self.lineSpace;
        var currentX = leftOffset;
        
        
        
        
        var max_w:CGFloat = 0
        var max_h:CGFloat = 0
        if (!self.singleLine && self.preferredMaxLayoutWidth > 0)
        {
            
            for (_,view) in subviews.enumerated()
            {
                
                view.setContentConstrainToHighLever()
                let size = view.intrinsicContentSize
                if let p_view = previewsView
                {
                    
                    let width = size.width;
                    currentX += itemMargin
                    
                    
                    
                    let w_info = currentX + width + rightOffset
                    
                    
                    
                    if (w_info <= self.preferredMaxLayoutWidth)
                    {
                        if w_info > max_w{
                            max_w = w_info
                        }
                        
                        let lays:TP.lays = [
                            [view,[p_view,ee.R,ee.L,itemMargin],[p_view,ee.Y,0.+1000]]
                        ]
                        
                        UIView.eelay(lays: UIView.eeformat(lays: lays), at: self)
//                        UIView.solay(lays: lays, at: self)
                        
                        
                        //                        view.snp.makeConstraints(closure: { (make) -> Void in
                        //                            tagsConstraints.append(
                        //                                make.leading.equalTo(p_view.snp.trailing).offset(itemMargin).constraint
                        //                            )
                        //                            tagsConstraints.append(
                        //                                make.centerY.equalTo(p_view.snp.centerY).constraint
                        //                            )
                        //                        })
                        currentX += size.width
                    }
                    else
                    {
                        //new line
                        
                        if w_info > max_w{
                            max_w = w_info
                        }
                        
                        let lays:TP.lays = [
                            [view,[p_view,ee.B,ee.T,itemVerticalMargin.+1000],[ee.L,leftOffset]]
                        ]
                        UIView.eelay(lays: UIView.eeformat(lays: lays), at: self)
//                        UIView.solay(lays: lays, at: self)
                        
                        
                        //                        view.snp.makeConstraints(closure: { (make) -> Void in
                        //                            tagsConstraints.append(
                        //                                make.top.greaterThanOrEqualTo(p_view.snp.bottom).offset(itemVerticalMargin).constraint
                        //                            )
                        //                            tagsConstraints.append(
                        //                                make.leading.equalTo(superView.snp.leading).offset(leftOffset).constraint
                        //                            )
                        //                        })
                        currentX = leftOffset + size.width
                    }
                }
                else
                {
                    //first one
                    self.eelay = [
                        [view,[ee.T.L,[topPadding.+1000,leftOffset]]]
                    ]
                    
                    
                    //                    view.snp.makeConstraints(closure: { (make) -> Void in
                    //                        tagsConstraints.append(
                    //                            make.top.equalTo(superView.snp.top).offset(topPadding).constraint
                    //                        )
                    //                        tagsConstraints.append(
                    //                            make.leading.equalTo(superView.snp.leading).offset(leftOffset).constraint
                    //                        )
                    //                    })
                    
                    currentX = currentX + size.width
                    if currentX > max_w{
                        max_w = currentX
                    }

                    max_h = topPadding + size.height + bottomOffset
                    
                }
                
                previewsView = view
            }
        }
        else
        {
            for view in subviews
            {
                let size = view.intrinsicContentSize
                
                if let p_view = previewsView
                {
                    
                    
                    self.eelay = [
                        [view,[p_view,ee.R,ee.L,itemMargin],[p_view,ee.Y,0.+1000]]
                    ]
                    
                    //                    view.snp.makeConstraints(closure: { (make) -> Void in
                    //                        tagsConstraints.append(
                    //                            make.leading.equalTo(p_view.snp.trailing).offset(itemMargin).constraint
                    //                        )
                    //                        tagsConstraints.append(
                    //                            make.centerY.equalTo(p_view.snp.centerY).constraint
                    //                        )
                    //                    })
                    
                    currentX += size.width
                    
                    if currentX > max_w{
                        max_w = currentX
                    }
                    

                    
                }
                else
                {
                    //first one
                    
                    
                    let lays:TP.lays = [
                        [view,[ee.T.L,[topPadding.+1000,leftOffset]]]
                    ]
                    UIView.eelay(lays: UIView.eeformat(lays: lays), at: self)
                    
                    //                    view.snp.makeConstraints(closure: { (make) -> Void in
                    //                        tagsConstraints.append(
                    //                            make.top.equalTo(superView.snp.top).offset(topPadding).constraint
                    //                        )
                    //
                    //                        tagsConstraints.append(
                    //                            make.leading.equalTo(superView.snp.leading).offset(leftOffset).constraint
                    //                        )
                    //                    })
                    currentX += size.width
                    if currentX > max_w{
                        max_w = currentX
                    }
                    
                    
                }
                previewsView = view
                
            }
        }
        
        
        if let prev = previewsView
        {
            
            self.eelay = [
                [prev,[ee.B,(-bottomOffset).+1000]]
            ]
            
        }
        
        
        
        
        
        //        previewsView?.snp.makeConstraints(closure: { (make) -> Void in
        //            tagsConstraints.append(
        //                make.bottom.equalTo(superView.snp.bottom).offset(-bottomOffset).constraint
        //            )
        //        })
        //
        
        let size = self.intrinsicContentSize
        self.frame = CGRect(x: frame.origin.x, y: frame.origin.y, width: size.width, height: size.height)
        self.didSetup = true
        
    }
    
    
    
    deinit
    {
    }
}



